package com.suning.sawp.service.impl.clerk;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.suning.nsfuaa.employee.EmployeeService;
import com.suning.nsfuaa.employee.dto.Employee;
import com.suning.rsf.consumer.ServiceLocator;
import com.suning.sawp.constants.ClerkConstants;
import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.constants.TMConstants;
import com.suning.sawp.dto.clerk.ChannelPackRtn;
import com.suning.sawp.dto.clerk.ClerkBindEbuyRtn;
import com.suning.sawp.dto.clerk.InvitationCodeInfo;
import com.suning.sawp.dto.clerk.MyInvitationCodeNew;
import com.suning.sawp.dto.clerk.MyInvitationCodeRtn;
import com.suning.sawp.dto.clerk.RedPonitTips;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.customer.MemberQueryBindPhone;
import com.suning.sawp.dto.esb.LocateMemberInfo;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.intf.bi.BiSaleAmountDaoService;
import com.suning.sawp.intf.clerk.ClerkService;
import com.suning.sawp.intf.clerk.InvitationCodeInfoService;
import com.suning.sawp.intf.esb.MemberInfoService;
import com.suning.sawp.intf.store.StoreInfoService;
import com.suning.sawp.intf.storeman.StoreManService;
import com.suning.sawp.intf.tm.vo.TimeMachineVo;
import com.suning.sawp.po.store.StoreInfo;
import com.suning.sawp.service.encrypt.EncryptUtil;
import com.suning.sawp.service.util.DJStringUtils;
import com.suning.sawp.service.util.HttpClientUtil;
import com.suning.sawp.service.util.RedisCacheUtils;
import com.suning.sawp.service.util.SCMConfigUtil;
import com.suning.slss.intf.service.qrcode.ShortCodeServiceRsf;
import com.suning.slss.intf.service.qrcode.data.ShortCodeResponse;
import com.suning.vgs.follow.remote.intf.StoreManRemoteService;
import com.suning.vgs.follow.remote.store.StoreManEbuyAccount;

/**
 * 
 * 店员相关服务实现类<br> 
 * 〈功能详细描述〉
 *
 * @author 12061818
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service
public class ClerkServiceImpl implements ClerkService{
	
	private static final Logger LOGGER = LoggerFactory.getLogger(ClerkServiceImpl.class);
	
	private static final String COMMON_CHANNELCODE = "quanguozbyyhz";
	
	private static final String COMMON_QRCODE = "http://mapp.suning.com/a.php?s=qrcode/offline&f=quanguozbyyhz&pack=com.suning.mobile.ebuy";
	
	// 邮箱正则
	private static Pattern emailPattern = 
            Pattern.compile(ClerkConstants.EMAIL_PATTERN);
	
	// 手机号正则
	private static Pattern mobilePattern = Pattern.compile("^1\\d{10}");
	
	private static final String REGISTER_SALT_KEY = "@@e2321ce4";
	
	ShortCodeServiceRsf shortCodeServiceRsf = ServiceLocator.getService(
            ShortCodeServiceRsf.class, "ShortCodeServiceRsfImpl");

	@Value("#{settingConfig[channelPackUrl]}")
	String channelPackUrl;
	
	/**
	 * follow 保存用户发展用户信息接口
	 */
	@Resource
	StoreManRemoteService storeManRemoteService;
	
	@Autowired
	StoreInfoService storeInfoService;
	
	@Autowired
	InvitationCodeInfoService invitationCodeInfoService;
	
	@Resource
	MemberInfoService memberInfoService;
	
	@Resource
	StoreManService storeManService;
	
	@Resource
	BiSaleAmountDaoService biSaleAmountDaoService;
	
	private EmployeeService employeeService = ServiceLocator.getService(EmployeeService.class, "");
	
	@Resource
    private RedisCacheUtils cacheUtils;
	
	public ReturnMsg<MyInvitationCodeRtn> getMyInvitationCode(String staffId) {
		LOGGER.info("获取店员邀请码,staffId:{}", staffId);
		ReturnMsg<MyInvitationCodeRtn> ret = new ReturnMsg<MyInvitationCodeRtn>();
		MyInvitationCodeRtn invitationCode = new MyInvitationCodeRtn();
		InvitationCodeInfo invitationInfo = null;
		StoreInfo storeInfo = null;
		
		String storeCode = storeManRemoteService.getStoreCodeByStaffId(staffId);
		if (StringUtils.isNotEmpty(storeCode) && !("null".equals(storeCode))){
			storeInfo = storeInfoService.queryStoreByCode(storeCode);
		}
		
		if (null != storeInfo && StringUtils.isNotEmpty(storeInfo.getRegionCode())){
			invitationInfo = invitationCodeInfoService.
					queryInvitationCodeByRegionCode(storeInfo.getRegionCode());
		}
		
		if (StringUtils.isBlank(storeCode) || "null".equals(storeCode) || 
				null == storeInfo || null == invitationInfo){
			invitationCode.setAreaName("通用");
			invitationCode.setChannelCode(COMMON_CHANNELCODE);
			invitationCode.setQrCode(COMMON_QRCODE);
		} else {
			String data = getChannelPackData(storeCode);
			if (StringUtils.isNotBlank(data)){
				invitationCode.setAreaName(storeInfo.getStoreName());
				invitationCode.setChannelCode(storeCode);
				invitationCode.setQrCode(data);
			} else {
				invitationCode.setAreaName(invitationInfo.getRegionName());
				invitationCode.setChannelCode(invitationInfo.getChannelCode());
				invitationCode.setQrCode(invitationInfo.getQrCode());
			}
		}
		StoreManEbuyAccount account = storeManRemoteService.queryStoreManEbuyAccount(staffId);
        if (null != account && StringUtils.isNotBlank(account.getCustNo())) {
            // 拼接扫码注册的链接地址
            String url = SCMConfigUtil.getConfig(ConfigConstants.MTS_REGISTER_URL);
            String param = account.getCustNo() + REGISTER_SALT_KEY;
            try {
                String traceId = EncryptUtil.encryptRSA(param, ConfigConstants.CMF_PRIVATE_KEY);
                String traceId2 = EncryptUtil.encryptRSA(param, ConfigConstants.MTS_PRIVATE_KEY);
                String registerUrl = url.replace("{traceId}", traceId).replace("{traceId2}", traceId2);
                String shortUrl = getShortUrl(registerUrl);
                if (StringUtils.isNotBlank(shortUrl)) {
                    invitationCode.setRegisterUrl(shortUrl);
                } else {
                    invitationCode.setRegisterUrl(registerUrl);
                }
                invitationCode.setEbuyNum(account.getMaskeEbuyNo());
            } catch (Exception e) {
                LOGGER.error("ClerkService.getMyInvitationCode error. staffId:{}", staffId, e);
            }
        }
        ret.setData(invitationCode);
        
		return ret;
	}

	@Override
    public ReturnMsg<MyInvitationCodeNew> getMyInvitationCodeNew(String staffId) {
	    ReturnMsg<MyInvitationCodeNew> returnMsg = new ReturnMsg<MyInvitationCodeNew>();
	    MyInvitationCodeNew codeNew = null;
	    StoreManDto storeManDto = storeManService.queryStoreManAttachInfo(staffId);
	    if (null != storeManDto && StringUtils.isNotBlank(storeManDto.getStoreCode())) {
	        codeNew = new MyInvitationCodeNew();
	        // 取登录信息且门店信息不为空
	        StoreManEbuyAccount account = storeManRemoteService.queryStoreManEbuyAccount(staffId);
	        // 查询绑定易购账号是否存在
	        if (null != account && StringUtils.isNotBlank(account.getCustNo())) {
	            codeNew.setEbuyBindFlag(MyInvitationCodeNew.EbuyBindFlag.BIND);
	            String shortUrl = getQcodeUrl(storeManDto.getStoreCode(), account.getCustNo(), staffId);
	            if (StringUtils.isNotBlank(shortUrl)) {
	                // 拼接扫码跳转链接
	                codeNew.setqCodeUrl(shortUrl);
	            } else {
	                // 前面折腾了半天还是没有手机号的话，报错
	                LOGGER.warn("getMyInvitationCodeNew staffId:{},getQcodeUrl fail", staffId);
	                returnMsg.setError(ErrorCodeConstants.ERR_0035);
	            }
	        } else {
	            codeNew.setEbuyBindFlag(MyInvitationCodeNew.EbuyBindFlag.UN_BIND);
	        }
	    } else {
	        LOGGER.warn("getMyInvitationCodeNew staffId:{},no storeCode", staffId);
	        returnMsg.setError(ErrorCodeConstants.ERR_0035);
	    }
	    returnMsg.setData(codeNew);
        return returnMsg;
    }
	
	/**
	 * 
	 * 功能描述: 拼接获取扫码注册链接<br>
	 * 〈功能详细描述〉
	 *
	 * @param storeCode
	 * @param custNum
	 * @param staffId
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private String getQcodeUrl(String storeCode, String custNum, String staffId) {
	    String shortUrl = null;
	    // 查询绑定的易购账号对应的绑定手机号
        MemberQueryBindPhone bindPhone = memberInfoService.queryBindPhone(custNum);
        String mobile = null;
        if (null == bindPhone) {
            // 如果会员中台没有查到绑定手机号信息，那么取HR中的手机信息，优先取私人手机号
            Employee employee = employeeService.queryEmployeeBasicInfo(staffId);
            if (StringUtils.isNotBlank(employee.getPersonalCellphone())) {
                mobile = employee.getPersonalCellphone();
            } else if (StringUtils.isNotBlank(employee.getCompanyCellphone())) {
                mobile = employee.getCompanyCellphone();
            }
        } else {
            mobile = bindPhone.getMobileNum();
        }
        if (StringUtils.isNotBlank(mobile)) {
            // 拼接扫码跳转链接
            String url = SCMConfigUtil.getConfig(ConfigConstants.MTS_Q_CODE_URL);
            if (StringUtils.isNotBlank(url)) {
                String qcodeUrl = url.replace("{storeCode}", storeCode)
                        .replace("{custNum}", custNum).replace("{staffNum}", mobile);
                shortUrl = getShortUrl(qcodeUrl);
            }
        } else {
            // 前面折腾了半天还是没有手机号的话，报错
            LOGGER.warn("getMyInvitationCodeNew staffId:{},no find any mobile", staffId);
        }
        
        return shortUrl;
	}
	
	/**
	 * 
	 * 功能描述: 取短链接<br>
	 * 〈功能详细描述〉
	 *
	 * @param url
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private String getShortUrl(String url) {
	    try {
	        ShortCodeResponse shortCodeResponse = shortCodeServiceRsf.buildShortCode(url, 90);
	        if (null != shortCodeResponse && StringUtils.isNotBlank(shortCodeResponse.getShortUrl())) {
	            return shortCodeResponse.getShortUrl();
	        } 
        } catch (Exception e) {
            LOGGER.error("invoke shortCodeServiceRsf.buildShortCode error, url:{}", url, e);
        }
	    LOGGER.warn("invoke shortCodeServiceRsf.buildShortCode can't get shortUrl. url:{}", url);
        return null;
	}
	
	/**
	 * 获取门店专属易购包的下载链接
	 * @param storeCode
	 * @return
	 */
	private String getChannelPackData(String storeCode){
		String data = "";
		try {
		    String url = String.format(channelPackUrl, storeCode);
		    LOGGER.debug("ClerkService.getChannelPackData url:{}", url);
			String dataRtn = HttpClientUtil.getData(url);
			Gson gson = new Gson();
			ChannelPackRtn channelInfo = gson.fromJson(dataRtn, ChannelPackRtn.class);
			data = channelInfo.getData();
		} catch (Exception e) {
			LOGGER.error("获取门店专属易购包的下载链接失败,storeCode = "+storeCode+",error = "+e);
		}
		return data;
	}

    @Override
    public ReturnMsg<String> clerkBindEbuyNo(String ebuyNo, String staffId) {
        LOGGER.info("ClerkService.clerkBindEbuyNo, ebuyNo:{}, staffId:{}", ebuyNo, staffId);
        ReturnMsg<String> returnMsg = new ReturnMsg<String>();
        LocateMemberInfo memberInfo = memberInfoService.locateMember(ebuyNo);
        if (null != memberInfo && StringUtils.isNotBlank(memberInfo.getCustNum())) {
            // 易购账号，查询到对应会员编码
            String maskeEbuyNo = "";
            Matcher mobileMatcher = mobilePattern.matcher(ebuyNo);
            if (mobileMatcher.matches()) {
                // 易购账号为手机号
                maskeEbuyNo = DJStringUtils.desensitiseMobile(ebuyNo);
            } else {
                // 判断易购账号是否为邮箱
                Matcher emailMatcher = emailPattern.matcher(ebuyNo);
                if (emailMatcher.matches()) {
                    maskeEbuyNo = DJStringUtils.desensitiseEmail(ebuyNo);
                }
            }
            // 绑定会员编码，至店员个人信息, 判断此用户是否已有绑定记录，若是更换绑定易购账号，记录更换记录
            if (StringUtils.isNotBlank(maskeEbuyNo)) {
                storeManRemoteService.bindStoreManEbuyNo(staffId, ebuyNo, maskeEbuyNo, memberInfo.getCustNum());
            }
            // 绑定成功，返回脱敏易购账号
            returnMsg.setData(maskeEbuyNo);
            
			// 更新缓存信息，加入易购账号信息
			String key = TMConstants.TIME_MACHINE_KEY + staffId;
			String data = cacheUtils.get(key);
			Gson gson = new Gson();
			if (StringUtils.isNotEmpty(data)) {
				TimeMachineVo vo = gson.fromJson(data, TimeMachineVo.class);
				if (vo != null && vo.getUserInfo() != null) {
					vo.getUserInfo().setEbuyNo(maskeEbuyNo);
					cacheUtils.setex(key, TMConstants.EXPIRE_TIME, gson.toJson(vo));
				}
			}
			
			key = TMConstants.EBUY_NO_KEY + staffId;
			data = cacheUtils.get(key);
			if (StringUtils.isNotEmpty(data)) {
				StoreManEbuyAccount account = gson.fromJson(data, StoreManEbuyAccount.class);
				if (account != null ) {
					account.setMaskeEbuyNo(maskeEbuyNo);
					account.setEbuyNo(ebuyNo);
					account.setCustNo(memberInfo.getCustNum());
					cacheUtils.setex(key, TMConstants.EXPIRE_TIME, gson.toJson(account));
				}
			}
            
        } else {
            // 易购账号，未能查询到对应会员编码
            returnMsg.setError(ErrorCodeConstants.ERR_1023);
        }
        return returnMsg;
    }

    @Override
    public ReturnMsg<StoreManEbuyAccount> queryBindEbuyNo(String staffId) {
        ReturnMsg<StoreManEbuyAccount> returnMsg = new ReturnMsg<StoreManEbuyAccount>();
        StoreManEbuyAccount ebuyAccount = storeManRemoteService.queryStoreManEbuyAccount(staffId);
        if (null != ebuyAccount) {
            StoreManEbuyAccount data = new StoreManEbuyAccount();
            data.setMaskeEbuyNo(ebuyAccount.getMaskeEbuyNo());
            returnMsg.setData(data);
        }
        return returnMsg;
    }
    
    @Override
    public String getRegisterUrl(String memberNo) {
        String url = SCMConfigUtil.getConfig(ConfigConstants.MTS_REGISTER_URL);
        String param = memberNo + REGISTER_SALT_KEY;
        String returnUrl = "";
        try {
            String traceId = EncryptUtil.encryptRSA(param, ConfigConstants.CMF_PRIVATE_KEY);
            String traceId2 = EncryptUtil.encryptRSA(param, ConfigConstants.MTS_PRIVATE_KEY);
            String registerUrl = url.replace("{traceId}", traceId).replace("{traceId2}", traceId2);
            String shortUrl = getShortUrl(registerUrl);
            returnUrl = StringUtils.isNotBlank(shortUrl) ? shortUrl : registerUrl;
        } catch (Exception e) {
            LOGGER.error("ClerkService.getRegisterUrl error. memberNo:{}", memberNo, e);
        }
        return returnUrl;
    }
    @Override
    public ReturnMsg<RedPonitTips> queryMyRedPointTips(String staffId) {
        LOGGER.info("ClerkService.queryMyRedPointTips IN, staffId:{}", staffId);
        ReturnMsg<RedPonitTips> retMsg = new ReturnMsg<RedPonitTips>();
        RedPonitTips ponitTips = new RedPonitTips();
        StoreManDto manDto = storeManService.queryStoreManAttachInfo(staffId);
        if (null != manDto && StringUtils.isNotBlank(manDto.getStoreCode())
                && ClerkConstants.STORE_KEEPER.equals(manDto.getPositionId())) {
            String latestSaleMon = biSaleAmountDaoService.queryLatestSaleMonth(manDto.getStoreCode());
            ponitTips.setLatestSaleMon(latestSaleMon);
            retMsg.setData(ponitTips);
        } else {
            LOGGER.error("ClerkService.queryMyRedPointTips no storeCode or no storeKeeper, staffId:{}", staffId);
            retMsg.setError(ErrorCodeConstants.ERR_0001);
        }
        return retMsg;
    }

    @Override
    public ReturnMsg<ClerkBindEbuyRtn> clerkBindEbuyNoNew(String ebuyNo, String staffId) {
        LOGGER.info("ClerkService.clerkBindEbuyNoNew, ebuyNo:{}, staffId:{}", ebuyNo, staffId);
        ReturnMsg<ClerkBindEbuyRtn> returnMsg = new ReturnMsg<ClerkBindEbuyRtn>();
        StoreManDto manDto = storeManService.queryStoreManAttachInfo(staffId);
        if (manDto == null || StringUtils.isBlank(manDto.getStoreCode())) {
            LOGGER.warn("ClerkService.clerkBindEbuyNoNew staffId:{}, no storeCode", staffId);
            returnMsg.setError(ErrorCodeConstants.ERR_0035);
            return returnMsg;
        }
        LocateMemberInfo memberInfo = memberInfoService.locateMember(ebuyNo);
        if (null != memberInfo && StringUtils.isNotBlank(memberInfo.getCustNum())) {
            // 易购账号，查询到对应会员编码
            String maskeEbuyNo = "";
            Matcher mobileMatcher = mobilePattern.matcher(ebuyNo);
            if (mobileMatcher.matches()) {
                // 易购账号为手机号
                maskeEbuyNo = DJStringUtils.desensitiseMobile(ebuyNo);
            } else {
                // 判断易购账号是否为邮箱
                Matcher emailMatcher = emailPattern.matcher(ebuyNo);
                if (emailMatcher.matches()) {
                    maskeEbuyNo = DJStringUtils.desensitiseEmail(ebuyNo);
                }
            }
            // 绑定会员编码，至店员个人信息, 判断此用户是否已有绑定记录，若是更换绑定易购账号，记录更换记录
            if (StringUtils.isNotBlank(maskeEbuyNo)) {
                storeManRemoteService.bindStoreManEbuyNo(staffId, ebuyNo, maskeEbuyNo, memberInfo.getCustNum());
            }
            // 绑定成功，返回脱敏易购账号
            ClerkBindEbuyRtn rtn = new ClerkBindEbuyRtn();
            rtn.setMaskeEbuyNo(maskeEbuyNo);
            // 拼接扫码跳转链接
            String url = getQcodeUrl(manDto.getStoreCode(), memberInfo.getCustNum(), staffId);
            rtn.setqCodeUrl(url);
            returnMsg.setData(rtn);
        } else {
            // 易购账号，未能查询到对应会员编码
            returnMsg.setError(ErrorCodeConstants.ERR_1023);
        }
        
        return returnMsg;
    }

}
